﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Confucius.dao;
using System.Collections.Generic;
using Confucius.entity;
using System.Windows.Resources;
using System.Xml.Linq;
using System.Linq;
using DBContent.Model;
using Confucius.utils;

namespace Confucius.daoImpl
{
    public class QuestDAOImpl : QuestDAO
    {
        public QuestDAOImpl(){}


        public List<Quest> retreiveQuests(String gameID) 
        {
            List<Quest> quests = new List<Quest>();
            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/quest.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var questRecords = from record in loadedData.Descendants("quest")
                                  select record;

                foreach (XElement record in questRecords)
                {
                    Quest newQuest = new Quest();

                    newQuest.QuestID = (string)record.Element("questID").Value;
                    newQuest.IconID = (string)record.Element("iconID").Value;
                    newQuest.CompleteText = (string)record.Element("completeText").Value;
                    newQuest.QuestOrder = Convert.ToInt32((string)record.Element("questOrder").Value);
                    newQuest.Lng = (float)Convert.ToDouble((string)record.Element("lng").Value);
                    newQuest.Lat = (float)Convert.ToDouble((string)record.Element("lat").Value);
                    newQuest.Title = (string)record.Element("title").Value;
                    newQuest.StartText = (string)record.Element("startText").Value;
                    // Get status from DB
                    DBQuest dbQuest = new DBQuest();
                    dbQuest.QuestID = newQuest.QuestID;
                    String questStatus = ConfuciusDBHelper.getQuestStatus(dbQuest);
                    newQuest.Status = questStatus;

                    quests.Add(newQuest);
                }
            }
            catch (Exception e)
            {
                throw new Exception("Could not load triggerIDs from DB. Info is: " + e.Message);
            }

            return quests;
        }

        public List<Quest> getFinishedQuests(String gameID, int currentOrder)
        {
            List<Quest> quests = new List<Quest>();
            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/quest.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var questRecords = from record in loadedData.Descendants("quest")
                                   select record;

                foreach (XElement record in questRecords)
                {
                    int order = Convert.ToInt32((string)record.Element("questOrder").Value);

                    if (order < currentOrder)
                    {
                        Quest newQuest = new Quest();

                        newQuest.QuestID = (string)record.Element("questID").Value;
                        newQuest.IconID = (string)record.Element("iconID").Value;
                        newQuest.CompleteText = (string)record.Element("completeText").Value;
                        newQuest.QuestOrder = Convert.ToInt32((string)record.Element("questOrder").Value);
                        newQuest.Lng = (float)Convert.ToDouble((string)record.Element("lng").Value);
                        newQuest.Lat = (float)Convert.ToDouble((string)record.Element("lat").Value);
                        newQuest.Title = (string)record.Element("title").Value;
                        newQuest.StartText = (string)record.Element("startText").Value;
                        // Get status from DB
                        DBQuest dbQuest = new DBQuest();
                        dbQuest.QuestID = newQuest.QuestID;
                        String questStatus = ConfuciusDBHelper.getQuestStatus(dbQuest);
                        newQuest.Status = questStatus;

                        quests.Add(newQuest);
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Could not load triggerIDs from DB. Info is: " + e.Message);
            }

            return quests;
        }

        public void updateQuestStatus(String questID, String status) 
        {
            DBQuest dbQuest = new DBQuest();
            dbQuest.QuestID = questID;
            dbQuest.Status = status;
            // Save the current date
            DateTime currentDate = new DateTime();
            if (status.Equals(Quest.START_STATUS))
            {
                dbQuest.StartTime = currentDate.ToString("yyyy-MM-dd HH:mm:ss");
            }
            else if (status.Equals(Quest.COMPLETE_STATUS)) 
            {
                String start = "";
                start = ConfuciusDBHelper.getQuestStartTime(dbQuest);

                // If did not start yet
                if (start == null)
                {
                    dbQuest.Duration = "0:0:0";
                    ConfuciusDBHelper.updateQuestStatus(dbQuest);
                    
                    return;
                }

                // If started before
                DateTime startDate = DateTime.ParseExact(start, "yyyy-MM-dd HH:mm:ss",
                                  null);
                int secs = 0; 
                int mins = 0; 
                int hours = 0;
                if (startDate != null)
                {
                    DateTime endDate = currentDate;
                    secs = (int)((endDate.Second - startDate.Second) / 1000);
                    hours = secs / 3600;
                    secs = secs % 3600;
                    mins = secs / 60;
                    secs = secs % 60;
                }
                String duration = Convert.ToString(hours) + ":" + Convert.ToString(mins) + ":" + Convert.ToString(secs);
                dbQuest.Duration = duration;
            }
            ConfuciusDBHelper.updateQuestStatus(dbQuest);
        }

        public Quest readQuest(String questID, String gameID) 
        {
            Quest quest = new Quest();

            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/quest.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var quests = from record in loadedData.Descendants("quest")
                            select record;

                foreach (XElement questRecord in quests)
                {
                    string id = (string)questRecord.Element("questID").Value;
                    if (id.Equals(questID))
                    {
                        quest.QuestID = id;
                        quest.Title = (string)questRecord.Element("title").Value;
                        quest.IconID = (string)questRecord.Element("iconID").Value;
                        quest.StartText = (string)questRecord.Element("startText").Value;
                        quest.CompleteText = (string)questRecord.Element("completeText").Value;

                        // Get status and duration from DB
                        DBQuest dbQuest = new DBQuest();
                        dbQuest.QuestID = id;
                        String questStatus = ConfuciusDBHelper.getQuestStatus(dbQuest);
                        String questDuration = ConfuciusDBHelper.getQuestDuration(dbQuest);
                        quest.Status = questStatus;
                        quest.Duration = questDuration;
                        break;
                    }
                }

            }
            catch (Exception e)
            {
                throw new Exception("Could not read Quest from DB. Info is: " + e.Message);
            }

            return quest;
        }
    }
}
